home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / c / rdir.zip / RDIR.C < prev    next >
C/C++ Source or Header  |  1987-06-14  |  23KB  |  752 lines

  1. /*
  2.  * RDIR.C : A resident directory lister.  This shows how to access DOS from
  3.  *          within a Turbo C resident program.  To completely recompile this
  4.  *          code you must have MASM or a compatible compiler.  Unfortunately
  5.  *          everything but trapping the BIOS Disk service software
  6.  *          interrrupt could be done in Turbo C.  See code commentary.
  7.  *
  8.  *  To activate the program once loaded, press Ctrl and Alt together.
  9.  *  I know this combination gets in the way of SideKick, but I don't use
  10.  *  sidekick <grin> and this is meant as a tutorial anyway.  If you would
  11.  *  like to change this combination see Hot_Combo in the source code.
  12.  *  Next, enter the pattern for the directory search followed either by
  13.  *  Enter or Ctrl-Enter.  Enter will not include directories.  Ctrl-Enter
  14.  *  will include directories.  Directories are displayed in white where
  15.  *  other files are displayed in cyan.  Hidden and system files are included.
  16.  *  The page up and page down keys may be used to see other parts of large
  17.  *  directory listings.
  18.  *
  19.  *  Written by Dean D. McCrory
  20.  *  For Turbo C 1.00
  21.  *  May 14, 1987
  22.  *
  23.  *  Compile with:
  24.  *    masm -mx bioshand.asm;
  25.  *    masm -mx intvid.asm;
  26.  *    tcc -N- rdir.c bioshand.obj intvid.obj
  27.  *
  28.  *  The -N- switch turns stack checking off which is a definite requirement
  29.  *  for writing ISRs.  Have fun <grin>.
  30.  */
  31.  
  32. #include <dos.h>
  33. #include <dir.h>
  34.  
  35. #include "intvid.h"
  36.  
  37. /* function prototypes */
  38. int main (void);
  39. unsigned prgsize (void);
  40. void exit (int);
  41. char far * getdosbusy (void);
  42. void interrupt timer_handler (void);
  43. void do_click (void);
  44. void interrupt special_handler (void);
  45. void interrupt keyboard_handler (void);
  46. extern void interrupt biosdisk_handler (void);
  47. void interrupt break_handler (void);
  48. void list_directory (void);
  49. void set_screen (void);
  50. void get_pattern (void);
  51. void display_entries (void);
  52. void find_entry (void);
  53. void sc_putsa (int, int, char *, int);
  54. void sc_putca (int, int, char, int);
  55. void sc_repvca (int, int, char, int, int);
  56. void sc_rephca (int, int, char, int, int);
  57. void sc_savbox (int, int, int, int, char *);
  58. void sc_resbox (int, int, int, int, char *);
  59. void sc_rptpos (int *, int *);
  60. void sc_setpos (int, int);
  61. char far * sc_cca (int, int);
  62. int getkey ();
  63.  
  64. /* Define the structure which will be attached to interrupt d0 so we can
  65.    determine if rdir is already loaded */
  66. typedef struct s_rdir_cfg
  67.    {
  68.    char iret;        /* iret first, just in case */
  69.    long * signature; /* signature string */
  70.    } t_rdir_cfg;
  71.  
  72. /* Suppress some library functions to conserve space */
  73. _setargv () {}
  74. _setenvp () {}
  75.  
  76. /* defines for various things, in alot of these things we are looking right
  77.    into the BIOS data area. See Peter Norton's Guide to the IBM-PC or
  78.    your Tech. Ref. for an expanation of these data items. */
  79. #define Screen_Ram   ((char far *) 0xb8000000L) + (*(int far *) 0x0000044eL)
  80. #define Display_Page (*(char far *) 0x00000462L)
  81. #define Iret         0xcf     /* for iret in int d1 just in case */
  82. #define Intr         0xd1     /* interrupt for install checking */
  83. #define Timer        0x1c     /* timer interrupt number */
  84. #define Keyboard     0x09     /* keyboard hardware interrupt */
  85. #define Special      0x28     /* special interrupt 28h */
  86. #define Critical     0x24     /* hardware critical interrupt 24h */
  87. #define Break        0x1b     /* bios ctrl-break interrupt */
  88. #define BiosDisk     0x13     /* bios diskette services */
  89. #define NotOk        1        /* already installed return code */
  90. #define Ok           0        /* success return code */
  91. #define Shift_Bits   ((char far *) 0x00000417L)
  92. #define Hot_Combo    ((*Shift_Bits & 12) == 12) /* Our hot key combo */
  93.  
  94. #define  Box_Row     4     /* row of box */
  95. #define  Box_Col     4     /* column of box */
  96. #define  Box_Hgt     17    /* height of box */
  97. #define  Box_Wdth    70    /* widht of box */
  98. #define  Box_Attr    0x4f  /* attribute of box border */
  99. #define  Box_Incr    14    /* number of columns between start of filenames */
  100. #define  Pat_Size    64    /* size of a pattern string */
  101. #define  Norm_Attr   3     /* attribute of normal files */
  102. #define  Dir_Attr    15    /* attribute of directories */
  103. #define  Name_Size   12    /* size of each file name when displayed */
  104. #define  Per_Screen  5 * (Box_Hgt - 2) /* number of dir entries in box */
  105.  
  106. /* Defines for key values as returned by getkey () */
  107. #define  Page_Up_Key    329
  108. #define  Page_Dn_Key    337
  109. #define  Escape_Key     27
  110. #define  BackSpace_Key  8
  111. #define  Enter_Key      13
  112. #define  Ctrl_Enter_Key 10
  113.  
  114. char  box_buf[Box_Hgt * Box_Wdth * 2]; /* buffer for saving screen */
  115. int   old_row, old_col;                /* row and col of cursor */
  116. int   current_entry;                   /* last dir entry read */
  117. int   entries_to_skip;                 /* first entry on display */
  118. char  pattern[Pat_Size];               /* pattern for dir searches */
  119. int   attrib;                          /* attrib for dir searches */
  120. struct ffblk ffblk;                    /* file-find block */
  121. int   key, status;                     /* last key, and last ff status */
  122. t_vidreg regs;                         /* global regs structure */
  123. char far * ptr;                        /* general purpose far pointer */
  124. char far * buf_pos;                    /* another of the same */
  125. int   next_line;                       /* used by screen stuff */
  126.  
  127. /* Our configuration structure... nothing in it but the signature */
  128. t_rdir_cfg rdir_cfg =
  129.    {
  130.    Iret, (long *) "rdir"
  131.    };
  132.  
  133. void interrupt (* old_timer) ();    /* previous timer interrupt vector */
  134. void interrupt (* old_keyboard) (); /* previous keyboard int vector */
  135. void interrupt (* old_special) ();  /* previous int 28h vector */
  136. void interrupt (* old_biosdisk) (); /* previous bios disk svc vector */
  137. void interrupt (* old_critical) (); /* previous int 24h vector */
  138. void interrupt (* old_break) ();    /* pervious int 1bh vector */
  139. char far * old_dta;                 /* disk transfer address save area */
  140.  
  141. static char far * dosbusy_fl;    /* dos maintains this */
  142. char biosbusy_fl = 0;            /* I maintain this */
  143. static int request_fl = 0;       /* 0 - no request
  144.                                     1 - request made
  145.                                     2 - request being serviced
  146.                                   */
  147. int main ()
  148. {
  149.    t_rdir_cfg far * cfg_ptr;
  150.  
  151.    /* get old configuration information (mayebe) */
  152.    cfg_ptr = (t_rdir_cfg far *) getvect (Intr);
  153.  
  154.    /* check to see if we are already installed */
  155.    if (*cfg_ptr->signature != *rdir_cfg.signature)
  156.       {
  157.       /* we were not installed so install ourselves */
  158.       old_timer = getvect (Timer);
  159.       old_keyboard = getvect (Keyboard);
  160.       old_special = getvect (Special);
  161.       old_biosdisk = getvect (BiosDisk);
  162.       setvect (Timer, timer_handler);
  163.       setvect (Special, special_handler);
  164.       setvect (BiosDisk, biosdisk_handler);
  165.       setvect (Keyboard, keyboard_handler);
  166.       setvect (Intr, (void interrupt (*) ()) &rdir_cfg);
  167.       dosbusy_fl = getdosbusy ();
  168.       keep (Ok, prgsize ());
  169.       }
  170.  
  171.    return (NotOk);
  172. }
  173.  
  174. /* prgsize ()
  175.  *
  176.  * Calculates the program size by looking at __brklvl which is set to
  177.  * the end of initialized and uninitialized data whithin the data segment
  178.  * at program startup.  __brklvl is then changed as memory space is
  179.  * malloc'd.  __brklvl is decremented as malloc'd areas are free'd.
  180.  *
  181.  *   ** This function should work in Tiny, Small, and Meduim models **
  182.  */
  183.  
  184. unsigned prgsize ()
  185. {
  186.    extern unsigned __brklvl;     /* current top of heap == sbrk (0) */
  187.    extern unsigned _psp;         /* lowest segment address occupied */
  188.  
  189.    return (_DS + (__brklvl + 15) / 16 - _psp);
  190. }
  191.  
  192. /* exit ()
  193.  *
  194.  * Rewrite exit for memory conservation.  This exit () does not close files
  195.  * or flush buffers, which is fine in this case because we have no open
  196.  * files or buffers which need to be flushed.
  197.  *
  198.  */
  199. void exit (status)
  200.    int status;
  201. {
  202.    _exit (status);
  203. }
  204.  
  205. /* getdosbusy ()
  206.  *
  207.  * Gets the Dos busy flag th